//
//  MainViewController.m
//  LegoClient
//
//  Created by Balazs Faludi on 30.12.09.
//  Copyright Universität Basel 2009. All rights reserved.
//

#import "MainViewController.h"
#import "MainView.h"
#import "NetClient.h"
#import "NetConnection.h"
#import "NetMessage.h"
#import "NetCommand.h"
#import "TiltIndicator.h"
#import <AudioToolbox/AudioToolbox.h>
#import "XIGame.h"
#import "RadarScene.h"
#import "XIUtilities.h"

#define kScannerWidthMultiplier 0.05

@implementation MainViewController

#pragma mark -
#pragma mark Initializations & Destructor

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}

 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	[super viewDidLoad];
	
	[XIGame sharedGame].renderView = glView;
	[[XIGame sharedGame] start];
	//[[XIGame sharedGame] enableAccelerometer];
	
	radarScene = [[RadarScene alloc] init];
	[XIGame sharedGame].activeScene = radarScene;
	
	radarScene.scannerWidth = 200.0 * kScannerWidthMultiplier;
	radarScene.scannerOn = NO;
	
	neutralAngle = M_PI / 4.0f;
	isOn = FALSE;
	
	filter = [[LowpassFilter alloc] initWithSampleRate:60.0 cutoffFrequency:20.0];
	
	accelerometer = [UIAccelerometer sharedAccelerometer];
	accelerometer.delegate = self;
	accelerometer.updateInterval = 0.01667;
	
	sendTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(sendControlSignals) userInfo:nil repeats:YES];
	
	client = [[NetClient alloc] initWithType:@"_rc._tcp"];
	client.delegate = self;
	[client searchServices];
	
	//tiltIndicator.pinImageView.image = [UIImage imageNamed:@"TiltPin.png"];
	//tiltIndicator.backgroundImageView.image = [UIImage imageNamed:@"TiltBG.png"];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
	return toInterfaceOrientation == UIInterfaceOrientationLandscapeRight;
}

- (void)dealloc {
	[accelerometer release];
	[client release];
	[connection release];
	[tiltIndicator release];
	//[lastAcc release];
	[onoffSwitch release];
	[filter release];
	[radarScene release];
    [super dealloc];
}

#pragma mark -
#pragma mark NetClientDelegate protocol

- (void)client:(NetClient *)aclient didFindServices:(NSArray *)services
{
	[aclient connectToService:[services lastObject]];
}

- (void)client:(NetClient *)client connected:(NetConnection *)aconnection
{
	connection = aconnection;
	connection.delegate = self;
}

#pragma mark -
#pragma mark Command Handling

- (void) handleCollision {
    AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
	[onoffSwitch setOn:NO animated:YES];
	isOn = NO;
}

- (void)receivedSensorDataAngle:(int)angle distance:(int)distance {
	[radarScene addAngle:angle distance:distance];
}


#pragma mark -
#pragma mark NetConnectionDelegate protocol

- (void)connectionLost:(NetConnection *)connection {
	NSLog(@"Connection lost");
}

- (void)connection:(NetConnection *)connection receivedMessage:(NetMessage *)message
{
	NSLog(@"Received: %@", [message stringValue]);
	NetCommand *command = [[NetCommand alloc] initWithMessage:message];
	if([[command head] isEqualToString:@"BUMP"]) [self handleCollision];
	else if([[command head] isEqualToString:@"SCRS"]) {
		[self receivedSensorDataAngle:[[command getArgumentAtIndex:0] intValue] distance:[[command getArgumentAtIndex:1] intValue]];
	}
}

#pragma mark -
#pragma mark Accelerometer

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
	[filter addAcceleration:acceleration];
	
	/*if(lastAcc) [lastAcc release];
	lastAcc = [acceleration retain];*/
	
	float angle = asinf(-filter.x);
	float neutralizedAngle = angle - neutralAngle;
	float angleLimit = M_PI / 8.0f;
	float y = limit(neutralizedAngle / angleLimit, -1.0f, 1.0f);
	float x = -limit(filter.y / 0.5f, -1.0f, 1.0f);
	x = deadZone(x, -0.05, 0.05);
	y = deadZone(y, -0.05, 0.05);
	lastX = x;
	lastY = y;
	
	tiltIndicator.value = CGPointMake(x, y);
		
}

- (void)sendControlSignals {
	if(isOn) {
		NetCommand *accCommand = [[NetCommand alloc] initWithHead:@"CTRL" body:[NSString stringWithFormat:@"%f %f", lastX, -lastY]];
		[connection sendMessage:[accCommand message]];
		//[connection sendMessage:[accCommand message]];
		//[connection sendMessage:[accCommand message]];
		//[connection sendMessage:[accCommand message]];
		//[connection sendMessage:[accCommand message]];
	}
}

- (IBAction)setNeutralAction:(id)sender {
	neutralAngle = asinf(-filter.x);
}

#pragma mark -
#pragma mark Control commands

- (IBAction)turnOnOff:(id)sender {
	isOn = !isOn;
	NSString *body = isOn ? @"1" : @"0";
	NetCommand *command = [[NetCommand alloc] initWithHead:@"ONOF" body:body];
	[connection sendMessage:[command message]];
	//NSString *text = isOn ? @"Turn off" : @"Turn on";
	//[onoffButton setTitle:text forState:UIControlStateNormal];
}

- (IBAction)radarSwitchAction:(id)sender {
	BOOL on = radarSwitch.on;
	radarScene.scannerOn = on;
	NSString *body = on ? @"1" : @"0";
	NetCommand *command = [[NetCommand alloc] initWithHead:@"SCAN" body:body];
	[connection sendMessage:[command message]];
}

- (IBAction)setSpeedAction:(id)sender {
	int speed = (int)round(speedSlider.value);
	radarScene.scannerWidth = speed * kScannerWidthMultiplier;
	NSString *body = [NSString stringWithFormat:@"%i%", speed];
	NetCommand *command = [[NetCommand alloc] initWithHead:@"SCSP" body:body];
	[connection sendMessage:[command message]];
}

#pragma mark -
#pragma mark FlipsideView

- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller {
    
	[self dismissModalViewControllerAnimated:YES];
}

- (IBAction)showInfo {    
	
	FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
	controller.delegate = self;
	
	controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
	[self presentModalViewController:controller animated:YES];
	
	[controller release];
}

@end
